package com.credithc.fastdfs.monitor.service.impl;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.csource.common.MyException;
import org.csource.fastdfs.ProtoCommon;
import org.csource.fastdfs.StructGroupStat;
import org.csource.fastdfs.StructStorageStat;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.credithc.fastdfs.api.entity.Group;
import com.credithc.fastdfs.api.entity.Storage;
import com.credithc.fastdfs.api.mapper.StorageDayMapper;
import com.credithc.fastdfs.api.mapper.StorageHourMapper;
import com.credithc.fastdfs.api.mapper.StorageMapper;
import com.credithc.fastdfs.monitor.jsonbean.Line;
import com.credithc.fastdfs.monitor.service.MonitorService;
import com.credithc.fastdfs.monitor.util.NumUtil;
import com.credithc.fastdfs.util.FastdfsUtil;
import com.credithc.fastdfs.api.entity.StorageDay;
import com.credithc.fastdfs.api.entity.StorageHour;
import com.credithc.framework.core.mybatis.page.PageDto;

@Service("monitorServiceImpl")
public class MonitorServiceImpl implements MonitorService {

	private static final Logger logger = LoggerFactory
			.getLogger(MonitorServiceImpl.class);

	@Autowired
	private StorageMapper storageMapper;

	@Autowired
	private StorageHourMapper storageHourMapper;

	@Autowired
	private StorageDayMapper storageDayMapper;

	@Override
	public List<Group> listGroupInfo() throws IOException, MyException {
		List<Group> result = new ArrayList<Group>();
		TrackerClient trackerCilent = FastdfsUtil.getInstance()
				.getTrackerClient();
		TrackerServer trackerServer = FastdfsUtil.getInstance()
				.getTrackerServer();
		if (trackerServer == null) {
			return result;
		}
		StructGroupStat[] groupStats = trackerCilent.listGroups(trackerServer);
		if (groupStats == null) {
			logger.error("ERROR! list groups error, error no: "
					+ trackerCilent.getErrorCode());
			return result;
		}
		logger.info("group count: " + groupStats.length);
		Date date = new Date();

		for (StructGroupStat groupStat : groupStats) {
			Group group = new Group();
			BeanUtils.copyProperties(groupStat, group);
			StructStorageStat[] storageStats = trackerCilent.listStorages(
					trackerServer, groupStat.getGroupName());
			for (StructStorageStat storageStat : storageStats) {
				Storage storage = new Storage();
				BeanUtils.copyProperties(storageStat, storage);
				storage.setCreated(date);
				storage.setCurStatus(ProtoCommon
						.getStorageStatusCaption(storageStat.getStatus()));
				group.getStorageList().add(storage);
			}
			result.add(group);
		}

		FastdfsUtil.getInstance().closeTrackerServer(trackerServer);

		return result;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Line> listStorageCpuLines(String groupName) throws IOException,
			MyException {
		List<Line> lines = new ArrayList<Line>();
		List<Storage> storages = listStorage(groupName);
		for (Storage s : storages) {
			PageDto page = new PageDto();
			page.setPage(1);
			page.setRows(10);
			List<Storage> results = storageMapper.getStorageByIpAddr(
					page.createPage(), s.getIpAddr());
			Line line1 = new Line(s.getIpAddr() + "CPU使用率");
			for (int i = results.size() - 1; i >= 0; i--) {
				Storage ss = results.get(i);
				line1.getData().add(
						new Object[] { ss.getCreated().getTime(),
								Double.parseDouble(ss.getCpu()) });

			}
			lines.add(line1);
		}
		return lines;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Line> listStorageMemLines(String groupName) throws IOException,
			MyException {
		List<Line> lines = new ArrayList<Line>();
		List<Storage> storages = listStorage(groupName);
		for (Storage s : storages) {
			PageDto page = new PageDto();
			page.setPage(1);
			page.setRows(10);
			List<Storage> results = storageMapper.getStorageByIpAddr(
					page.createPage(), s.getIpAddr());
			Line line = new Line(s.getIpAddr() + "MEM使用率");
			for (int i = results.size() - 1; i >= 0; i--) {
				Storage ss = results.get(i);
				line.getData()
						.add(new Object[] { ss.getCreated().getTime(),
								ss.getMem() });
			}
			lines.add(line);
		}
		return lines;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Storage> listStorage(String groupName) throws IOException,
			MyException {
		return storageMapper.getIpAddrByGroupName(groupName);
	}

	@Override
	public List<Line> getNetTrafficLines(String ip, String start, String end,
			String searchType) throws IOException, MyException {
		// 查询参数
		HashMap<String, Object> map = new HashMap<String, Object>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date starttime, endtime;
		List<Line> lines = new ArrayList<Line>();
		try {
			starttime = sdf.parse(start);
			endtime = sdf.parse(end);
			map.put("ip", ip);
			map.put("starttime", starttime);
			map.put("endtime", endtime);
			List storages = new ArrayList();
			if (searchType.equals("day")) {
				storages = storageDayMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("hour")) {
				storages = storageHourMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("min")) {
				storages = storageMapper
						.getStorageByConditionsForCapacityLines(map);
			}
			Line line = new Line(ip + " 上传流量");
			Line linedown = new Line(ip + " 下载流量");
			for (int i = 0; i < storages.size(); i++) {
				if (searchType.equals("day")) {
					if (i != 0) {// 不操作第一条数据
						StorageDay sBefore = (StorageDay) storages.get(i - 1);
						StorageDay s = (StorageDay) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalUploadBytes() - s.getTotalUploadBytes())) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalDownloadloadBytes() - s.getTotalDownloadloadBytes())) });
					}
				} else if (searchType.equals("hour")) {
					if (i != 0) {// 不操作第一条数据
						StorageHour sBefore = (StorageHour) storages.get(i - 1);
						StorageHour s = (StorageHour) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalUploadBytes() - s.getTotalUploadBytes())) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalDownloadloadBytes() - s.getTotalDownloadloadBytes())) });
					}
				} else if (searchType.equals("min")) {
					if (i != 0) {// 不操作第一条数据
						Storage sBefore = (Storage) storages.get(i - 1);
						Storage s = (Storage) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalUploadBytes() - s.getTotalUploadBytes())) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										NumUtil.transByteToMB(Math.abs(sBefore.getTotalDownloadloadBytes() - s.getTotalDownloadloadBytes())) });
					}
				}
			}
			lines.add(line);
			lines.add(linedown);
		} catch (ParseException e) {
			logger.info("数据解析异常 [getNetTrafficLines]");
		}
		return lines;
	}

	@Override
	public List<Line> getCapacityLines(String ip, String start, String end,
			String searchType) throws IOException, MyException {
		// 查询参数
		HashMap<String, Object> map = new HashMap<String, Object>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date starttime, endtime;
		List<Line> lines = new ArrayList<Line>();
		try {
			starttime = sdf.parse(start);
			endtime = sdf.parse(end);
			map.put("ip", ip);
			map.put("starttime", starttime);
			map.put("endtime", endtime);
			List storages = new ArrayList();
			if (searchType.equals("day")) {
				storages = storageDayMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("hour")) {
				storages = storageHourMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("min")) {
				storages = storageMapper
						.getStorageByConditionsForCapacityLines(map);
			}
			Line line = new Line(ip + " 已使用容量");
			Line line1 = new Line(ip + " 未使用容量");
			for (int i = 0; i < storages.size(); i++) {
				if (searchType.equals("day")) {
						StorageDay s = (StorageDay) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										s.getTotalMB()- s.getFreeMB() });
						line1.getData().add(new Object[] { s.getCreated().getTime(), s.getFreeMB() });
				} else if (searchType.equals("hour")) {
						StorageHour s = (StorageHour) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										s.getTotalMB() - s.getFreeMB() });
						line1.getData().add(new Object[] { s.getCreated().getTime(), s.getFreeMB() });
				} else if (searchType.equals("min")) {
						Storage s = (Storage) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										s.getTotalMB() - s.getFreeMB() });
						line1.getData().add(new Object[] { s.getCreated().getTime(), s.getFreeMB() });
				}
			}
			lines.add(line1);
			lines.add(line);
		} catch (ParseException e) {
			logger.info("数据解析异常 [getCapacityLines]");
		}
		return lines;
	}

	@Override
	public List<Line> getFileCountLines(String ip, String start, String end,
			String searchType) throws IOException, MyException {
		// 查询参数
		HashMap<String, Object> map = new HashMap<String, Object>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date starttime, endtime;
		List<Line> lines = new ArrayList<Line>();
		try {
			starttime = sdf.parse(start);
			endtime = sdf.parse(end);
			map.put("ip", ip);
			map.put("starttime", starttime);
			map.put("endtime", endtime);
			List storages = new ArrayList();
			if (searchType.equals("day")) {
				storages = storageDayMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("hour")) {
				storages = storageHourMapper
						.getStorageByConditionsForCapacityLines(map);
			} else if (searchType.equals("min")) {
				storages = storageMapper
						.getStorageByConditionsForCapacityLines(map);
			}
			Line line = new Line(ip + " 上传数量");
			Line linedown = new Line(ip + " 下载数量");
			for (int i = 0; i < storages.size(); i++) {
				if (searchType.equals("day")) {
					if (i != 0) {// 不操作第一条数据
						StorageDay sBefore = (StorageDay) storages.get(i - 1);
						StorageDay s = (StorageDay) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalUploadCount() - s.getTotalUploadCount()) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalDownloadCount() - s.getTotalDownloadCount()) });
					}
				} else if (searchType.equals("hour")) {
					if (i != 0) {// 不操作第一条数据
						StorageHour sBefore = (StorageHour) storages.get(i - 1);
						StorageHour s = (StorageHour) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalUploadCount() - s.getTotalUploadCount()) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalDownloadCount() - s.getTotalDownloadCount()) });
					}
				} else if (searchType.equals("min")) {
					if (i != 0) {// 不操作第一条数据
						Storage sBefore = (Storage) storages.get(i - 1);
						Storage s = (Storage) storages.get(i);
						line.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalUploadCount() - s.getTotalUploadCount()) });
						linedown.getData().add(
								new Object[] { s.getCreated().getTime(),
										Math.abs(sBefore.getTotalDownloadCount() - s.getTotalDownloadCount()) });
					}
				}
			}
			lines.add(line);
			lines.add(linedown);
		} catch (ParseException e) {
			logger.info("数据解析异常 [getFileCountLines]");
		}
		return lines;
	}

}
